home *** CD-ROM | disk | FTP | other *** search
/ 130 MIDI Tool Box / 130 MIDI Tool Box.iso / midiexsr / midiint.asm < prev    next >
Assembly Source File  |  1986-11-14  |  11KB  |  373 lines

  1. PAGE    60,132
  2.  
  3. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  4. ; MIDIINT.ASM -- Assembler subroutines for MIDIEX patch exchange utility
  5. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  6.  
  7. ; COPYRIGHT (C) 1986 John Bailin, Cantus Corporation
  8. ;
  9. ; Date:        01/02/86
  10. ;
  11. ; Changed 08/24/86 Jim Bergsten to function using the Microsoft "C"
  12. ; compiler. Summary of changes:
  13. ;     1. PAGE statement added for better output listing.
  14. ;     2. Entry point names prefixed with "_".
  15. ;     3. GROUP, PROG, SEGMENT statements changed to match Microsoft
  16. ;     small model standards.
  17. ;     4. Unnecessary stack subtracts and adds removed.
  18. ;     5. Other corrections, simplifications...
  19. ;
  20. ; Changed 11/14/86 by Michael Geary - fixed several bugs
  21. ;
  22. ;
  23. ; Note: Linkage conventions assume the Microsoft C compiler small model.
  24.  
  25. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  26. ; equates
  27.  
  28. mpudata equ    330h            ; mpu data port address.
  29. mpustat equ    331h            ; mpu status port address.
  30. mpucmd    equ    331h            ; mpu command port address.
  31. mpudsr    equ    80h            ; mpu data set ready, active low.
  32. mpudrr    equ    40h            ; mpu data read ready, active low.
  33.  
  34. loop_delay    equ    0ffffh        ; delay for timeouts.
  35.  
  36. BUFMAX    equ    8192            ; **MUST MATCH C CODE**
  37.  
  38. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  39.  
  40. _TEXT    SEGMENT  BYTE PUBLIC 'CODE'
  41. _TEXT    ENDS
  42. CONST    SEGMENT  PARA PUBLIC 'CONST'
  43. CONST    ENDS
  44. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  45. _BSS    ENDS
  46. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  47. _DATA    ENDS
  48. DGROUP    GROUP    CONST, _BSS, _DATA
  49.  
  50.     ASSUME    cs:_TEXT, ds:DGROUP, es:nothing, ss:nothing
  51.  
  52. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  53. ; data segment
  54.  
  55. _DATA    segment word public 'DATA'
  56.  
  57.     public    _recv_data_count,_recv_buf,_recv_buf_ptr
  58.     public    _fetch_buf_ptr
  59.     public    _wait_char
  60.  
  61. oldInt2     label    dword
  62. int_2_save    dw    ?,?
  63.  
  64. _recv_buf    db    BUFMAX dup (0)
  65. _recv_buf_end    label    byte
  66. _recv_data_count dw     0
  67. _recv_buf_ptr    dw    0
  68. _fetch_buf_ptr    dw    0
  69.  
  70. _wait_char     db     0
  71.  
  72. _DATA    ends
  73.  
  74. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  75. ; code segment
  76.  
  77. _TEXT    segment byte public 'CODE'
  78.  
  79.     public    _set_mpu_vector,_reset_mpu_vector,mpu_int,_int10
  80.     public    _write_mpu_command,_write_mpu_data,_get_char
  81.     public    _queue_mpu_data
  82.  
  83. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  84. ; Set the interrupt vector for the MPU/401
  85.  
  86. _set_mpu_vector  proc     near
  87.  
  88.     mov    ax,350ah        ; get current int 2
  89.     int    21h            ; dos does it.
  90.     mov    int_2_save,bx        ; save the vector offset.
  91.     mov    int_2_save+2,es     ; save the vector segment.
  92.     push    ds            ; save data segment.
  93.     mov    dx,offset mpu_int    ; offset for dos call.
  94.     mov    ax,seg mpu_int        ; segment for dos call
  95.     mov    ds,ax            ;
  96.     mov    ax,250ah            ; set vector call, int 2.
  97.     int    21h            ; dos installs vector.
  98.     pop    ds
  99.     cli                ; interrupts off.
  100.     in    al,21h            ; read 8259 address.
  101.     jmp    short $+2
  102.     and    al,0fbh         ; enable irq2.
  103.     out    21h,al            ;
  104.     call    _mpu_reset        ; reset the mpu, return code in AX
  105.     sti                ; interrupts back on.
  106.     ret                ; return to caller.
  107.  
  108. _set_mpu_vector  endp
  109.  
  110. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  111. ; Reset the interrupt vector for the MPU/401
  112.  
  113. _reset_mpu_vector     proc     near
  114.  
  115.     push    ds            ; save registers.
  116.     cli                ; interrupts off.
  117.     in    al,21h            ; read 8259.
  118.     jmp    short $+2
  119.     or    al,4            ; disable irq2.
  120.     out    21h,al            ; done.
  121.     sti                ; interrupts back on.
  122.     mov    ax,250ah            ; restore old int 2 vector.
  123.     mov    dx,int_2_save        ; get old offset into dx.
  124.     mov    ds,int_2_save+2     ; get old segment into ds.
  125.     int    21h            ; dos sets the vector.
  126.     pop    ds            ; restore registers.
  127.     ret                ; return to caller.
  128.  
  129. _reset_mpu_vector     endp
  130.  
  131. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  132. ; Reset the MPU/401
  133.  
  134. _mpu_reset     proc     near
  135.     cli                ; disable interrupts.
  136.  
  137.     mov    dx,mpustat        ; mpu status port.
  138.     mov    cx,loop_delay        ; delay counter.
  139. mr10:    in    al,dx            ; get the status.
  140.     and    al,mpudrr        ; test for data receive ready.
  141.     jz    mr15            ; ready.
  142.     loop    mr10            ; not ready.
  143.     xor    ax,ax            ; timed out.
  144.     jmp    short mr40        ; leave.
  145. mr15:    mov    ax,0ffh         ; get the command.
  146.     out    dx,al            ; send to mpu.
  147.     mov    cx,loop_delay        ; delay counter.
  148. mr20:    in    al,dx            ; get the status.
  149.     and    al,mpudsr        ; test for data set ready.
  150.     jz    mr30            ; ready.
  151.     loop    mr20            ; not ready.
  152.     xor    ax,ax            ; timed out.
  153.     jmp    short mr40        ; leave.
  154. mr30:    mov    dx,mpudata        ; mpu data port.
  155.     in    al,dx            ; read data.
  156.     mov    ax, 1
  157. mr40:
  158.     sti                ; interrupts back on.
  159.     ret                ; return to caller.
  160.  
  161. _mpu_reset     endp
  162.  
  163. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  164. ; Write a command to the MPU
  165. ; BOOL write_mpu_command( command-byte );
  166.  
  167. _write_mpu_command     proc     near
  168.  
  169.     push    bp            ; save caller's base pointer
  170.     mov    bp,sp            ; establish new base pointer.
  171.     mov    dx,mpustat        ; mpu status port.
  172.     mov    cx,loop_delay        ; loop counter for no response.
  173. wmc10:    in    al,dx            ; get the status.
  174.     and    al,mpudrr        ; test for data receive ready.
  175.     jz    wmc15            ; ready.
  176.     loop    wmc10            ; not ready.
  177.     xor    ax,ax            ; timed out.
  178.     jmp    short wmc30        ; leave.
  179. wmc15:    cli                ; interrupts off.
  180.     mov    ax,[bp+4]               ; get the command.
  181.     out    dx,al            ; send to mpu.
  182.     mov    cx,loop_delay        ; loop counter for no response.
  183. wmc20:    in    al,dx            ; get the status.
  184.     and    al,mpudsr        ; test for data set ready.
  185.     jz    wmc25            ; ready.
  186.     loop    wmc20            ; not ready.
  187.     xor    ax,ax            ; timed out.
  188.     jmp    short wmc30        ; leave.
  189. wmc25:    mov    dx,mpudata        ; mpu data port.
  190.     in    al,dx            ; read data.
  191.     cmp    al,0FEh         ; acknowledge?
  192.     je    wmc29            ; yes.
  193.     call    _queue_mpu_data     ; no. queue the data.
  194. wmc29:    mov    ax,1            ; normal return
  195. wmc30:    sti                ; interrupts back on.
  196.     pop    bp            ; get base pointer back.
  197.     ret                ; return to caller.
  198.  
  199. _write_mpu_command     endp
  200.  
  201. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  202. ; Write data to the MPU
  203. ; BOOL write_mpu_data( data-byte );
  204.  
  205. _write_mpu_data  proc     near
  206.  
  207.     push    bp            ; save caller's base pointer
  208.     mov    bp,sp            ; establish new base pointer.
  209.     mov    dx,mpustat        ; mpu status port.
  210.     mov    cx,loop_delay        ; loop counter for no response.
  211. wmd10:    in    al,dx            ; get the status.
  212.     and    al,mpudrr        ; test for data receive ready.
  213.     jz    wmd20            ; ready.
  214.     loop    wmd10            ; not ready.
  215.     xor    ax,ax            ; timed out.
  216.     jmp    short wmd30        ; leave.
  217. wmd20:    mov    dx,mpudata        ; mpu data port.
  218.     mov    ax,[bp+4]        ; get the byte to send.
  219.     out    dx,al            ; send to mpu.
  220.     mov    ax,1            ; normal return
  221. wmd30:    pop    bp            ; get base pointer back.
  222.     ret                ; return to caller.
  223.  
  224. _write_mpu_data  endp
  225.  
  226. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  227. ; MPU interrupt handler (IRQ2, INT 0Ah)
  228.  
  229. mpu_int proc    far
  230.  
  231.     push    ax            ; save regs.
  232.     push    dx
  233.     pushf
  234.     mov    dx,mpustat        ; mpu status port
  235.     in    al,dx            ; read status
  236.     rol    al,1            ; bit 7 into cy.
  237.     jb    mi90            ; not generated by mpu.
  238.     popf
  239.     sti                ; allow other interrupts
  240.     push    ds
  241.     mov    ax,DGROUP
  242.     mov    ds,ax
  243.     mov    dx,mpudata        ; ready. now get data port.
  244.     in    al,dx            ; get data.
  245.     cmp    al,0FEh         ; acknowledge?
  246.     je    mi30            ; yes. don't queue data.
  247.     cmp    _wait_char,0        ; waiting for a particular char?
  248.     je    mi20            ; no.
  249.     cmp    al,_wait_char        ; the char we're waiting for?
  250.     jne    mi20            ; no.
  251.     mov    _wait_char,0        ; yes. reset flag.
  252. mi20:    call    _queue_mpu_data     ; queue it up.
  253. mi30:    mov    al,20h            ; eoi to send to 8259.
  254.     out    20h,al            ; send it.
  255.     pop    ds            ; restore regs.
  256.     pop    dx
  257.     pop    ax
  258.     iret                ; return to caller.
  259.  
  260. mi90:    popf
  261.     pop    dx
  262.     pop    ax
  263.     jmp    oldInt2
  264.  
  265. mpu_int endp
  266.  
  267. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  268. ; queue received mpu data
  269. ; input -- al = received data
  270.  
  271. _queue_mpu_data  proc     near
  272.  
  273.     push    bx            ; save regs
  274.     cli                ; interrupts off.
  275.     mov    bx,_recv_buf_ptr    ; buffer ptr.
  276.     mov    _recv_buf[bx],al    ; store data.
  277.     inc    _recv_buf_ptr        ; increment the buffer pointer.
  278.     inc    _recv_data_count    ; increment the data count.
  279.     cmp    _recv_buf_ptr,BUFMAX    ; incremented past the end?
  280.     jb    qmd10            ; not yet.
  281.     mov    _recv_buf_ptr,0     ; yes. wrap around to zero.
  282. qmd10:    sti                ; interrupts back on.
  283.     pop    bx
  284.     ret                ; return to caller.
  285.  
  286. _queue_mpu_data  endp
  287.  
  288. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  289. ; fetch received mpu data (*not used*)
  290. ;
  291. ; input -- none
  292. ; output -- ah = 1 if data received, 0 if not.    al = data.
  293.  
  294. IF 0
  295.  
  296. _fetch_mpu_data  proc     near
  297.  
  298.     xor    ax, ax
  299.     cli                ; interrupts off.
  300.     mov    bx,_fetch_buf_ptr    ; buffer ptr.
  301.     cmp    bx,_recv_buf_ptr    ; any data?
  302.     je    fmd10            ; no, return
  303.     mov    al,_recv_buf[bx]    ; fetch data.
  304.     mov    ah, 1
  305.     inc    _fetch_buf_ptr        ; increment the buffer pointer.
  306.     cmp    _fetch_buf_ptr,_recv_buf_end  ; incremented past the end?
  307.     jb    fmd10            ; not yet.
  308.     mov    _fetch_buf_ptr,0    ; yes. wrap around to zero.
  309. fmd10:    sti                ; interrupts back on.
  310.     ret                ; return to caller.
  311.  
  312. _fetch_mpu_data  endp
  313.  
  314. ENDIF
  315.  
  316. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  317. ; bios int 16h call.
  318. ;
  319. ; calling convention get_char( mode ) ;
  320. ;
  321. ; input -- mode = 0 -- read next char, return result in al, scan code in ah.
  322.  
  323. ;    -- mode = 1 -- returns 1 if a char is available, 0 if not.
  324. ;    -- mode = 2 -- returns shift flags in al.
  325.  
  326. _get_char     proc     near
  327.  
  328.     push    bp            ; save caller's base pointer
  329.     mov    bp,sp            ; establish new base pointer.
  330.     mov    ax,[bp+4]            ; get mode.
  331.     xchg    ah,al            ; turn it around for bios call.
  332.     int    16h            ; do the bios call.
  333.     pushf                ; save flags.
  334.     cmp    word ptr [bp+4],1        ; check for char available?
  335.     jne    gc10            ; no. just return what bios returns.
  336.  
  337.     xor    ax,ax            ; assume no char.
  338.     popf                ; get flags back.
  339.     jz    gc20            ; no char available.
  340.     mov    ax,1            ; signal char available.
  341.     jmp    short gc20        ; continue.
  342. gc10:    popf                ; sync.
  343. gc20:    pop    bp            ; get base pointer back.
  344.     ret                ; return to caller.
  345.  
  346. _get_char     endp
  347.  
  348. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  349. ; bios int 10h c level call.
  350. ;
  351. ; calling convention int10( ax, bx, cx, dx )
  352. ;
  353.  
  354. _int10     proc     near
  355.  
  356.     push    bp            ; save caller's base pointer
  357.     mov    bp,sp            ; establish new base pointer.
  358.     mov    ax,[bp+4]        ; get register calling value.
  359.     mov    bx,[bp+6]        ; get register calling value.
  360.     mov    cx,[bp+8]        ; get register calling value.
  361.     mov    dx,[bp+10]        ; get register calling value.
  362.     int    10h            ; do the bios call.
  363.     pop    bp            ; get base pointer back.
  364.     ret                ; return to caller.
  365.  
  366. _int10     endp
  367.  
  368. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  369.  
  370. _TEXT    ends
  371.  
  372.     end
  373.